#ifndef __SE_EPOLL_EVENT_LOOP_HPP__
#define __SE_EPOLL_EVENT_LOOP_HPP__

#include "EventHandler.hpp"
#include "Acceptor.hpp"
#include "TcpConnection.hpp"

#include <sys/epoll.h>
#include <map>
#include <vector>

namespace se {

class EpollEventLoop {
public:
    EpollEventLoop(Acceptor &acceptor);

    /**
     * @brief 开始epoll事件循环
     * 
     */
    void start();

private:
    /**
     * @brief 增加监听的文件描述符
     * 
     * @param fileDescriptor 
     */
    void addFileDescriptor(int fileDescriptor);

    /**
     * @brief 删除不再监听的文件描述符
     * 
     * @param fileDescriptor 
     */
    void deleteFileDescriptor(int fileDescriptor);

    /**
     * @brief 当有新的TCP连接请求时的处理函数
     * 
     */
    void handlerNewTcpConnection();

    /**
     * @brief 当有TCP连接发来数据时的处理函数
     * 
     * @param clientFileDescriptor 
     */
    void handlerTcpMessage(int clientFileDescriptor);

public:
    /** 当TCP连接建立时的事件处理函数 */
    EventHandler<void (std::shared_ptr<TcpConnection>)> OnTcpConnected;
    
    /** 当TCP连接接收到数据时的事件处理函数 */
    EventHandler<void (std::shared_ptr<TcpConnection>)> OnTcpMessageReceived;

    /** 当TCP连接断开连接时的事件处理函数 */
    EventHandler<void (std::shared_ptr<TcpConnection>)> OnTcpClosed;

private:
    int _epollFileDescriptor;  // epoll对应的文件描述符
    bool _loopFlag;  // ture: 事件循环继续， false: 停止事件循环
    Acceptor &_acceptor;  // 监听TCP连接
    std::map<int, std::shared_ptr<TcpConnection>> _tcpConnections;  // tcp连接集合
    std::vector<struct epoll_event> _epollEventList;   // 就绪的文件描述符
};

}  // namespace se

#endif